package com.ybkj.daijia.server.service.impl;

import static com.ybkj.daijia.api.driver.v4.PayController.HELP_PAY_PROFIX;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ybkj.daijia.ServiceSetting;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.common.Distance;
import com.ybkj.daijia.common.PageVo;
import com.ybkj.daijia.common.Pager;
import com.ybkj.daijia.common.Principal;
import com.ybkj.daijia.common.RandomString;
import com.ybkj.daijia.common.SquareLocation;
import com.ybkj.daijia.config.ErrandUpApi;
import com.ybkj.daijia.config.ZhuanApi;
import com.ybkj.daijia.config.ZhuanxianApi;
import com.ybkj.daijia.page.Page;
import com.ybkj.daijia.page.Pageable;
import com.ybkj.daijia.page.domain.Sort;
import com.ybkj.daijia.page.domain.Sort.Direction;
import com.ybkj.daijia.page.impl.PageImpl;
import com.ybkj.daijia.page.impl.PageRequest;
import com.ybkj.daijia.server.event.model.DriverOnlineEvent;
import com.ybkj.daijia.server.freight.Truck;
import com.ybkj.daijia.server.mapper.CompanyMapper;
import com.ybkj.daijia.server.mapper.DriverApplyMapper;
import com.ybkj.daijia.server.mapper.DriverChoseLevelCarMapper;
import com.ybkj.daijia.server.mapper.DriverChoseLevelFreightMapper;
import com.ybkj.daijia.server.mapper.DriverChoseLevelMapper;
import com.ybkj.daijia.server.mapper.DriverChoseLevelPaotuiMapper;
import com.ybkj.daijia.server.mapper.DriverChoseLevelZhuanxianMapper;
import com.ybkj.daijia.server.mapper.DriverConsumedRecordMapper;
import com.ybkj.daijia.server.mapper.DriverEnchashmentMapper;
import com.ybkj.daijia.server.mapper.DriverGradeMapper;
import com.ybkj.daijia.server.mapper.DriverLevelMapper;
import com.ybkj.daijia.server.mapper.DriverLoginMapper;
import com.ybkj.daijia.server.mapper.DriverLoginRecordMapper;
import com.ybkj.daijia.server.mapper.DriverMapper;
import com.ybkj.daijia.server.mapper.DriverPaymentsRecordMapper;
import com.ybkj.daijia.server.mapper.DriverRebatePaymentRecordMapper;
import com.ybkj.daijia.server.mapper.DriverRechargeRecordMapper;
import com.ybkj.daijia.server.mapper.DriverTimeYearMapper;
import com.ybkj.daijia.server.mapper.OrderMapper;
import com.ybkj.daijia.server.mapper.PayRecordDriverMapper;
import com.ybkj.daijia.server.mapper.PhoneRecordMapper;
import com.ybkj.daijia.server.mapper.PhoneSmsRecordMapper;
import com.ybkj.daijia.server.mapper.UsuallyDriverMapper;
import com.ybkj.daijia.server.mapper.UsuallyEmployMapper;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.DriverChoseLevel;
import com.ybkj.daijia.server.model.DriverChoseLevelCar;
import com.ybkj.daijia.server.model.DriverChoseLevelFreight;
import com.ybkj.daijia.server.model.DriverChoseLevelPaotui;
import com.ybkj.daijia.server.model.DriverChoseLevelZhuanxian;
import com.ybkj.daijia.server.model.DriverEnchashment;
import com.ybkj.daijia.server.model.DriverGrade;
import com.ybkj.daijia.server.model.DriverLogin;
import com.ybkj.daijia.server.model.DriverLoginRecord;
import com.ybkj.daijia.server.model.DriverPaymentsRecord;
import com.ybkj.daijia.server.model.DriverRebatePaymentRecord;
import com.ybkj.daijia.server.model.HelpPayRecord;
import com.ybkj.daijia.server.model.Order;
import com.ybkj.daijia.server.model.PayRecordDriver;
import com.ybkj.daijia.server.model.PhoneRecord;
import com.ybkj.daijia.server.model.PhoneSmsRecord;
import com.ybkj.daijia.server.model.SmsTemplet;
import com.ybkj.daijia.server.model.SmsTemplet.SmsType;
import com.ybkj.daijia.server.model.UsuallyEmploy;
import com.ybkj.daijia.server.service.DriverHelppayService;
import com.ybkj.daijia.server.service.DriverService;
import com.ybkj.daijia.server.service.FreightService;
import com.ybkj.daijia.server.service.SmsService;
import com.ybkj.daijia.server.service.SuperviceService;
import com.ybkj.daijia.server.service.ZhuancheService;
import com.ybkj.daijia.server.service.ZhuanxianService;
import com.ybkj.daijia.server.zhuan.Car;
import com.ybkj.daijia.server.zhuan.CarTypeRel;
import com.ybkj.daijia.server.zhuanxian.Line;
import com.ybkj.daijia.serverUtils.ServiceUtil;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.serverUtils.UseAllDataUtil;
import java.io.File;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * @author Shine
 */
@Service
@Slf4j
public class DefaultDriverService implements DriverService {

    private static final Logger logger = LoggerFactory.getLogger(DefaultDriverService.class);

    @Autowired
    private DriverMapper driverMapper;

    @Autowired
    private UsuallyEmployMapper usuallyEmployMapper;

    @Autowired
    private DriverChoseLevelMapper driverChoseLevelMapper;

    @Autowired
    private DriverChoseLevelCarMapper driverChoseLevelCarMapper;

    @Autowired
    private DriverChoseLevelPaotuiMapper driverChoseLevelPaotuiMapper;

    @Autowired
    private DriverChoseLevelFreightMapper driverChoseLevelFreightMapper;

    @Autowired
    private DriverChoseLevelZhuanxianMapper driverChoseLevelZhuanxianMapper;

    @Autowired
    private DriverLevelMapper driverLevelMapper;

    @Autowired
    private DriverGradeMapper driverGradeMapper;

    @Autowired
    private UsuallyDriverMapper usuallyDriverMapper;

    @Autowired
    private PhoneRecordMapper phoneRecordMapper;

    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private DriverApplyMapper driverApplyMapper;

    @Autowired
    private PayRecordDriverMapper payRecordDriverMapper;

    @Autowired
    private SettingUtils settingUtils;

    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    @Autowired
    private DriverLoginMapper driverLoginMapper;

    @Autowired
    private DriverLoginRecordMapper driverLoginRecordMapper;

    @Autowired
    private DriverTimeYearMapper driverTimeYearMapper;

    @Autowired
    private DriverRechargeRecordMapper driverRechargeRecordMapper;

    @Autowired
    private DriverConsumedRecordMapper driverConsumedRecordMapper;

    @Autowired
    private DriverPaymentsRecordMapper driverPaymentsRecordMapper;

    @Autowired
    private DriverEnchashmentMapper driverEnchashmentMapper;

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private ZhuanApi zhuanApi;

    @Autowired
    private ErrandUpApi errandApi;

    @Autowired
    private ZhuanxianApi zhuanxianApi;

    @Autowired
    private ZhuanxianService zhuanxianService;

    @Autowired
    private FreightService freightService;


    @Autowired
    private SmsService smsService;

    @Autowired
    private SuperviceService superviceService;

    @Autowired
    private ZhuancheService zhuancheService;

    @Autowired
    private PhoneSmsRecordMapper phoneSmsRecordMapper;

    @Autowired
    private DriverHelppayService driverHelppayService;
    @Autowired
    private DriverRebatePaymentRecordMapper driverRebatePaymentRecordMapper;

    @Override
    public List<Driver> queryDriverByParams(String driverPhone, String driverName) {
        List<Driver> list = driverMapper.queryDriverByParams(driverPhone, driverName);
        return list;
    }

    @Override
    public Page<Driver> queryAll(String param, Integer status, Integer type) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Pageable pageable = new PageRequest(Pager.getPage(), Pager.getLimit());

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("offset", Pager.getOffset());
        params.put("size", Pager.getLimit());
        if (!principal.isCompanyType()) {
            params.put("companyId", principal.getCompanyId());
        }
        if (StringUtils.isNotEmpty(param)) {
            params.put("name", "%" + param + "%");
        }
        if (null != status) {
            params.put("status", status);
        }
        if (null != type) {
            if (type == 0) {
                params.put("type", Driver.DRIVER_TYPR_PARTTIME);
            } else if (type == 1) {
                params.put("type", Driver.DRIVER_TYPR_FULLTIME);
            }
        }

        List<Driver> content = driverMapper.selectByPage(params);
        long total = driverMapper.countByPage(params);

        if (total > 0) {
            for (Driver driver : content) {
                driver.setCompany(companyMapper.selectByPrimaryKey(driver.getCompanyId()));
            }
        }

        return new PageImpl<Driver>(content, pageable, total);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Driver insertRecord(Driver driver) {

        List<DriverChoseLevel> driverChoseLevels = driver.getDriverChoseLevels();
        List<DriverChoseLevelCar> driverChoseLevelCars = driver.getDriverChoseLevelCars();
        List<DriverChoseLevelPaotui> driverChoseLevelPaotuis = driver.getDriverChoseLevelPaotuis();
        List<DriverChoseLevelFreight> driverChoseLevelFreights = driver
            .getDriverChoseLevelFreights();
        List<DriverChoseLevelZhuanxian> driverChoseLevelZhuanxians = driver
            .getDriverChoseLevelZhuanxians();

        driverMapper.insertRecord(driver);

        if (!CollectionUtils.isEmpty(driverChoseLevels)) {
            for (DriverChoseLevel driverChoseLevel : driverChoseLevels) {
                if (null != driverChoseLevel.getDriverlevelId()) {
                    driverChoseLevel.setDriverId(driver.getId());
                    driverChoseLevelMapper.insertRecord(driverChoseLevel);
                }
            }
        }

        if (!CollectionUtils.isEmpty(driverChoseLevelCars)) {
            for (DriverChoseLevelCar driverChoseLevelCar : driverChoseLevelCars) {
                if (null != driverChoseLevelCar.getDriverlevelId()) {
                    driverChoseLevelCar.setDriverId(driver.getId());
                    driverChoseLevelCarMapper.insertRecord(driverChoseLevelCar);
                }
            }
        }

        if (!CollectionUtils.isEmpty(driverChoseLevelPaotuis)) {
            for (DriverChoseLevelPaotui driverChoseLevelPaotui : driverChoseLevelPaotuis) {
                if (null != driverChoseLevelPaotui.getDriverlevelId()) {
                    driverChoseLevelPaotui.setDriverId(driver.getId());
                    driverChoseLevelPaotuiMapper.insertRecord(driverChoseLevelPaotui);
                }
            }
        }

        if (!CollectionUtils.isEmpty(driverChoseLevelFreights)) {
            for (DriverChoseLevelFreight driverChoseLevelFreight : driverChoseLevelFreights) {
                if (null != driverChoseLevelFreight.getDriverlevelId()) {
                    driverChoseLevelFreight.setDriverId(driver.getId());
                    driverChoseLevelFreightMapper.insertRecord(driverChoseLevelFreight);
                }
            }
        }

        if (!CollectionUtils.isEmpty(driverChoseLevelZhuanxians)) {
            for (DriverChoseLevelZhuanxian driverChoseLevelZhuanxian : driverChoseLevelZhuanxians) {
                if (null != driverChoseLevelZhuanxian.getDriverlevelId()) {
                    driverChoseLevelZhuanxian.setDriverId(driver.getId());
                    driverChoseLevelZhuanxianMapper.insertRecord(driverChoseLevelZhuanxian);
                }
            }
        }

        return driver;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKey(Driver driver) {

        return driverMapper.updateByPrimaryKey(driver);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateInfo(Driver driver, String basePath, String carNumber) {

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();

        if (subject.isPermitted("otherdriverlevel")) {
            List<DriverChoseLevel> driverChoseLevels = driver.getDriverChoseLevels();
            List<DriverChoseLevelCar> driverChoseLevelCars = driver.getDriverChoseLevelCars();
            List<DriverChoseLevelPaotui> driverChoseLevelPaotuis = driver.getDriverChoseLevelPaotuis();
            List<DriverChoseLevelFreight> driverChoseLevelFreights = driver.getDriverChoseLevelFreights();

            driverChoseLevelMapper.deleteByDriver(driver.getId());
            if (!CollectionUtils.isEmpty(driverChoseLevels)) {
                for (DriverChoseLevel driverChoseLevel : driverChoseLevels) {
                    if (null != driverChoseLevel.getDriverlevelId()) {
                        driverChoseLevel.setDriverId(driver.getId());
                        driverChoseLevelMapper.insertRecord(driverChoseLevel);
                    }
                }
            }

            driverChoseLevelCarMapper.deleteByDriver(driver.getId());
            if (!CollectionUtils.isEmpty(driverChoseLevelCars)) {
                for (DriverChoseLevelCar driverChoseLevelCar : driverChoseLevelCars) {
                    if (null != driverChoseLevelCar.getDriverlevelId()) {
                        driverChoseLevelCar.setDriverId(driver.getId());
                        driverChoseLevelCarMapper.insertRecord(driverChoseLevelCar);
                    }
                }
            }

            driverChoseLevelPaotuiMapper.deleteByDriver(driver.getId());
            if (!CollectionUtils.isEmpty(driverChoseLevelPaotuis)) {
                for (DriverChoseLevelPaotui driverChoseLevelPaotui : driverChoseLevelPaotuis) {
                    if (null != driverChoseLevelPaotui.getDriverlevelId()) {
                        driverChoseLevelPaotui.setDriverId(driver.getId());
                        driverChoseLevelPaotuiMapper.insertRecord(driverChoseLevelPaotui);
                    }
                }
            }

            driverChoseLevelFreightMapper.deleteByDriver(driver.getId());
            if (!CollectionUtils.isEmpty(driverChoseLevelFreights)) {
                for (DriverChoseLevelFreight driverChoseLevelFreight : driverChoseLevelFreights) {
                    if (null != driverChoseLevelFreight.getDriverlevelId()) {
                        driverChoseLevelFreight.setDriverId(driver.getId());
                        driverChoseLevelFreightMapper.insertRecord(driverChoseLevelFreight);
                    }
                }
            }

        } else {
            List<DriverChoseLevel> driverChoseLevels = driver.getDriverChoseLevels();
            List<DriverChoseLevelCar> driverChoseLevelCars = driver.getDriverChoseLevelCars();
            List<DriverChoseLevelPaotui> driverChoseLevelPaotuis = driver.getDriverChoseLevelPaotuis();
            List<DriverChoseLevelFreight> driverChoseLevelFreights = driver.getDriverChoseLevelFreights();

            driverChoseLevelMapper.deleteByDriverAndCompany(driver.getId(), principal.getCompanyId());
            if (!CollectionUtils.isEmpty(driverChoseLevels)) {
                for (DriverChoseLevel driverChoseLevel : driverChoseLevels) {
                    if (null != driverChoseLevel.getDriverlevelId()) {
                        driverChoseLevel.setDriverId(driver.getId());
                        driverChoseLevelMapper.insertRecord(driverChoseLevel);
                    }
                }
            }

            driverChoseLevelCarMapper.deleteByDriverAndCompany(driver.getId(), principal.getCompanyId());
            if (!CollectionUtils.isEmpty(driverChoseLevelCars)) {
                for (DriverChoseLevelCar driverChoseLevelCar : driverChoseLevelCars) {
                    if (null != driverChoseLevelCar.getDriverlevelId()) {
                        driverChoseLevelCar.setDriverId(driver.getId());
                        driverChoseLevelCarMapper.insertRecord(driverChoseLevelCar);
                    }
                }
            }

            driverChoseLevelPaotuiMapper.deleteByDriverAndCompany(driver.getId(),
                principal.getCompanyId());
            if (!CollectionUtils.isEmpty(driverChoseLevelPaotuis)) {
                for (DriverChoseLevelPaotui driverChoseLevelPaotui : driverChoseLevelPaotuis) {
                    if (null != driverChoseLevelPaotui.getDriverlevelId()) {
                        driverChoseLevelPaotui.setDriverId(driver.getId());
                        driverChoseLevelPaotuiMapper.insertRecord(driverChoseLevelPaotui);
                    }
                }
            }

            driverChoseLevelFreightMapper.deleteByDriverAndCompany(driver.getId(),
                principal.getCompanyId());
            if (!CollectionUtils.isEmpty(driverChoseLevelFreights)) {
                for (DriverChoseLevelFreight driverChoseLevelFreight : driverChoseLevelFreights) {
                    if (null != driverChoseLevelFreight.getDriverlevelId()) {
                        driverChoseLevelFreight.setDriverId(driver.getId());
                        driverChoseLevelFreightMapper.insertRecord(driverChoseLevelFreight);
                    }
                }
            }

        }

        List<DriverChoseLevelZhuanxian> driverChoseLevelZhuanxians = driver
            .getDriverChoseLevelZhuanxians();
        if (!CollectionUtils.isEmpty(driverChoseLevelZhuanxians)) {
            driverChoseLevelZhuanxianMapper.deleteByDriver(driver.getId());
            for (DriverChoseLevelZhuanxian driverChoseLevelZhuanxian : driverChoseLevelZhuanxians) {
                if (null != driverChoseLevelZhuanxian.getDriverlevelId()) {
                    driverChoseLevelZhuanxian.setDriverId(driver.getId());
                    driverChoseLevelZhuanxianMapper.insertRecord(driverChoseLevelZhuanxian);
                }
            }
        }
        return driverMapper.updateByPrimaryKey(driver);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updatePushByPrimaryKey(Driver driver) {

        return driverMapper.updatePushByPrimaryKey(driver.getUserID(), driver.getDeviceType(),
            driver.getId());

    }

    @Override
    public Driver findOne(Long id) {
        Driver driver = driverMapper.selectByPrimaryKey(id);
        if (driver != null && driver.getGradeId() != null) {
            driver.setDriverGrade(driverGradeMapper.findById(driver.getGradeId()));
        }
        return driver;
    }

    @Override
    public Driver findByUsername(String username) {

        return driverMapper.selectByUsername(username);
    }

    @Override
    public List<Driver> findByIdIn(Long[] ids) {

        return driverMapper.selectByIdIn(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Driver driver, String basePath) {

        //上传监管平台
        driver.setFlag(3);
        superviceService.SjbaMessage(driver, basePath);

        usuallyDriverMapper.deleteByDriverId(driver.getId());
        driverRechargeRecordMapper.deleteByDriverId(driver.getId());
        driverConsumedRecordMapper.deleteByDriverId(driver.getId());
        driverPaymentsRecordMapper.deleteByDriverId(driver.getId());
        driverChoseLevelMapper.deleteByDriver(driver.getId());
        driverChoseLevelCarMapper.deleteByDriver(driver.getId());
        driverChoseLevelPaotuiMapper.deleteByDriver(driver.getId());
        driverChoseLevelFreightMapper.deleteByDriver(driver.getId());
        usuallyEmployMapper.deleteByEmploy(driver.getId());
        driverEnchashmentMapper.deleteByEmploy(driver.getId());

        driverTimeYearMapper.deleteByDriver(driver.getId());

        driverMapper.deleteByPrimaryKey(driver.getId());

    }

    @Override
    public void updateDriverTxAndTg(Driver driver) {
        driverMapper.updateDriverTxAndTg(driver);
    }

    @Override
    public String findLastestDriver() {
        Driver lastestDriver = driverMapper.findLastestDriver();
        String username = lastestDriver.getUsername();
        Integer usernameInt = Integer.parseInt(username);
        Integer newUsernameInt = usernameInt + 1;
        DecimalFormat df = new DecimalFormat("000000");
        String newUsername = df.format(newUsernameInt);
        return newUsername;
    }

    @Override
    public List<Driver> listRealTime(Long orderId) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Company company = companyMapper.selectByPrimaryKey(principal.getCompanyId());

        String cityName = company.getCityName();

        String driverJobType = "%" + Driver.DriverJobType.daijia.toString() + "%";

        if (principal.isCompanyType()) {
            return driverMapper.selectDiaodu(null, driverJobType);
        } else {
            return driverMapper.selectDiaodu(cityName, driverJobType);
        }

    }

    @Override
    public List<Driver> listdistance(Double longitude, Double latitude, String driverJobType) {

        SquareLocation squareLocation = Distance.returnSquarePoint(longitude, latitude, 50);

        if (StringUtils.isNotBlank(driverJobType)) {
            driverJobType = "%" + driverJobType + "%";
        }
        squareLocation.driverJobType = driverJobType;

        List<Driver> drivers = driverMapper.selectByNearly(squareLocation);

        DecimalFormat df = new DecimalFormat("#.00");

        if (!CollectionUtils.isEmpty(drivers)) {
            for (Driver driver : drivers) {
                // 计算距离
                double distance = Distance.doubleVal(latitude, longitude, driver.getLatitude(),
                    driver.getLongitude());
                driver.setDistance(Double.valueOf(df.format(distance)));
            }

            Collections.sort(drivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

        }

        return drivers;
    }

    @Override
    public List<Driver> listdiaodutuijian(Double longitude, Double latitude, Long orderId) {

        SquareLocation squareLocation = Distance.returnSquarePoint(longitude, latitude, 10);

        squareLocation.driverJobType = "%" + Driver.DriverJobType.daijia.toString() + "%";

        List<Driver> drivers = driverMapper.selectByNearly(squareLocation);

        DecimalFormat df = new DecimalFormat("#.00");

        if (!CollectionUtils.isEmpty(drivers)) {
            for (Driver driver : drivers) {
                // 计算距离
                double distance = Distance.doubleVal(latitude, longitude, driver.getLatitude(),
                    driver.getLongitude());
                driver.setDistance(Double.valueOf(df.format(distance)));
            }

            Collections.sort(drivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

        }

        return drivers;
    }

    @Override
    public Page<Driver> queryLessList(String param) {

        Setting setting = settingUtils.get();
        double lowestWorkVirtual = setting.getLowestWorkVirtual();
        Pageable pageable = new PageRequest(Pager.getPage(), Pager.getLimit());

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("offset", Pager.getOffset());
        params.put("size", Pager.getLimit());
        if (!principal.isCompanyType()) {
            params.put("companyId", principal.getCompanyId());
        }
        if (StringUtils.isNotEmpty(param)) {
            params.put("name", "%" + param + "%");
        }
        params.put("isFreeze", false);
        params.put("virtual", lowestWorkVirtual);

        List<Driver> content = driverMapper.selectByPage(params);
        long total = driverMapper.countByPage(params);

        if (total > 0) {
            for (Driver driver : content) {
                driver.setPhone(UseAllDataUtil.useAllDataDriver(driver.getPhone()));
                driver.setCompany(companyMapper.selectByPrimaryKey(driver.getCompanyId()));
            }
        }

        return new PageImpl<Driver>(content, pageable, total);
    }

    @Override
    public Page<Driver> queryFreezeList(String param) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Sort sort = new Sort(Direction.DESC, "id");

        Pageable pageable = new PageRequest(Pager.getPage(), Pager.getLimit(), sort);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("offset", Pager.getOffset());
        params.put("size", Pager.getLimit());
        params.put("isFreeze", true);
        if (!principal.isCompanyType()) {
            params.put("companyId", principal.getCompanyId());
        }
        if (StringUtils.isNotEmpty(param)) {
            params.put("name", "%" + param + "%");
        }

        List<Driver> content = driverMapper.selectByPage(params);
        long total = driverMapper.countByPage(params);

        if (total > 0) {
            for (Driver driver : content) {
                driver.setCompany(companyMapper.selectByPrimaryKey(driver.getCompanyId()));
            }
        }

        return new PageImpl<Driver>(content, pageable, total);
    }

    @Override
    public Page<PhoneRecord> queryRecordlist(String param) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Pageable pageable = new PageRequest(Pager.getPage(), Pager.getLimit());

        Long companyId = null;
        String likeName = null;
        if (!principal.isCompanyType()) {
            companyId = principal.getCompanyId();
        }
        if (StringUtils.isNotEmpty(param)) {
            likeName = "%" + param + "%";
        }

        List<PhoneRecord> content = phoneRecordMapper.selectByCompanyAndLike(companyId, likeName,
            Pager.getOffset(), Pager.getLimit());
        long total = phoneRecordMapper.countByCompanyAndLike(companyId, likeName);
        if (!CollectionUtils.isEmpty(content)) {

            for (PhoneRecord phoneRecord : content) {
                phoneRecord
                    .setDriverPhone(UseAllDataUtil.useAllDataDriver(phoneRecord.getDriverPhone()));
                phoneRecord.setMemberPhone(UseAllDataUtil.useAllData(phoneRecord.getMemberPhone()));

                Date call = phoneRecord.getPhoneDate();

                Calendar calendar = Calendar.getInstance();
                calendar.setTime(call);

                calendar.add(Calendar.MINUTE, 30);
                Date end = calendar.getTime();

                calendar.add(Calendar.MINUTE, -60);
                Date start = calendar.getTime();

                long orderCounts = orderMapper
                    .countByMemberWithServerTime(phoneRecord.getMemberId(),
                        start, end);

                if (orderCounts > 0) {
                    phoneRecord.setHasOrders(true);
                } else {
                    phoneRecord.setHasOrders(false);
                }

            }
        }

        return new PageImpl<PhoneRecord>(content, pageable, total);

    }

    @Override
    public Driver findByIdCard(String idCard) {

        return driverMapper.selectByIdCard(idCard);

    }

    @Override
    public Driver findByPhone(String phone) {

        return driverMapper.selectByPhone(phone);
    }

    @Override
    // 查询本公司（全部）服务人员
    public List<Driver> listByCompany() {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        return driverMapper.selectByTypeAndFreeze(null, false, principal.isCompanyType() ? null
            : principal.getCompanyId());
    }

    @Override
    // 附近服务人员
    public PageVo<Driver> queryNearDrivers(Double longitude, Double latitude, Integer page,
        Integer limit) {

        Setting setting = settingUtils.get();

        Double km = setting.getNearDriversKm();

        SquareLocation squareLocation = Distance.returnSquarePoint(longitude, latitude, km);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("offset", page * limit);
        params.put("size", limit);
        params.put("rightBottomLat", squareLocation.rightBottomLat);
        params.put("leftTopLat", squareLocation.leftTopLat);
        params.put("leftTopLng", squareLocation.leftTopLng);
        params.put("rightBottomLng", squareLocation.rightBottomLng);

        List<Driver> drivers = driverMapper.selectByPageNearlyWorking(params);
        long total = driverMapper.countByPageNearlyWorking(params);
        if (!setting.isAllowCallDriver()) {
            if (!CollectionUtils.isEmpty(drivers)) {
                for (Driver driver : drivers) {
                    Company company = companyMapper.selectByPrimaryKey(driver.getCompanyId());
                    driver.setPhone(company.getTelephone());
                }
            }
        }

        PageVo<Driver> vo = new PageVo<Driver>();
        vo.setContent(drivers);
        vo.setTotalElements(total);

        return vo;
    }

    @Override
    public List<Driver> queryNearDrivers(Double longitude, Double latitude, String jobType) {
        Setting setting = settingUtils.get();

        Double km = setting.getNearDriversKm();
        Integer amount = setting.getNearDriversAmount();

        SquareLocation squareLocation = new SquareLocation();
        if (km != 0) {
            squareLocation = Distance.returnSquarePoint(longitude, latitude, km);
        }
        if (StringUtils.isNotBlank(jobType)) {
            squareLocation.driverJobType = "%" + jobType + "%";
        }

        List<Driver> allDrivers = driverMapper.selectByNearlyWorking(squareLocation);

        if (!CollectionUtils.isEmpty(allDrivers)) {
            for (Driver driver : allDrivers) {
                // 计算距离
                double distance = Distance.doubleVal(latitude, longitude, driver.getLatitude(),
                    driver.getLongitude());
                driver.setDistance(distance);
                DecimalFormat df = new DecimalFormat("#.00");
                if (distance >= 1) {
                    driver.setDistanceStr(df.format(distance) + "公里");
                } else {
                    driver.setDistanceStr((long) (distance * 1000) + "米");
                }
            }

            Collections.sort(allDrivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

            Collections.sort(allDrivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getStatus().compareTo(arg1.getStatus());
                }
            });
        }

        if (!CollectionUtils.isEmpty(allDrivers) && amount != 0 && allDrivers.size() > amount) {
            allDrivers = allDrivers.subList(0, amount);
        }

        return allDrivers;
    }

    /****
     * $$$  回调
     * @param payRecordDriver
     * @param trade_no
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cashRecharge(PayRecordDriver payRecordDriver, String trade_no) {

        Driver driver = driverMapper.selectByPrimaryKey(payRecordDriver.getDriverId());
        if (null != driver) {
            Setting setting = settingUtils.get();
            logger.debug("cashRecharge");
            String type = DriverEnchashment.HELP_PAY;
            if (payRecordDriver.getTradeNO().startsWith(HELP_PAY_PROFIX)) {
                //可代付余额充值订单
                HelpPayRecord helpPayRecord = new HelpPayRecord();
                if (payRecordDriver.getPayRecordType()
                    .equals(PayRecordDriver.PayRecordTypeDriver.alipay)) {
                    helpPayRecord.setOperateType(HelpPayRecord.DRIVER_ALI_PAY);
                    helpPayRecord.setChangeMoney(payRecordDriver.getAmount());
                    helpPayRecord.setDriverId(driver.getId());
                    helpPayRecord
                        .setMemo("司机" + driver.getUsername() + "[" + driver.getId() + "]支付宝充值" +
                            payRecordDriver.getAmount().doubleValue() + "; ");
                } else if (payRecordDriver.getPayRecordType()
                    .equals(PayRecordDriver.PayRecordTypeDriver.wx)) {
                    helpPayRecord.setOperateType(HelpPayRecord.DRIVER_WEIXIN_PAY);
                    helpPayRecord.setChangeMoney(payRecordDriver.getAmount());
                    helpPayRecord.setDriverId(driver.getId());
                    helpPayRecord
                        .setMemo("司机" + driver.getUsername() + "[" + driver.getId() + "]微信充值" +
                            payRecordDriver.getAmount().doubleValue() + "; ");
                } else if (payRecordDriver.getPayRecordType().equals(
                    PayRecordDriver.PayRecordTypeDriver.unionpay)) {
                } else if (payRecordDriver.getPayRecordType().equals(
                    PayRecordDriver.PayRecordTypeDriver.bestpay)) {
                }
                helpPayRecord.setTradeNo(trade_no);
                driverHelppayService.operateDriverMoney(helpPayRecord);
            } else {
                driver.setVirtual(driver.getVirtual().add(payRecordDriver.getAmount()));
                driverMapper.updateVirtualByPrimaryKey(driver.getVirtual(), driver.getId());
                type = DriverEnchashment.AMOUT;
                //余额充值订单
                DriverPaymentsRecord driverPaymentsRecord = new DriverPaymentsRecord();
                driverPaymentsRecord.setMoney(payRecordDriver.getAmount());
                driverPaymentsRecord.setAfterMoney(driver.getVirtual());
                driverPaymentsRecord.setDriverId(driver.getId());
                driverPaymentsRecord.setDriverRealName(driver.getRealname());
                driverPaymentsRecord.setDriverUserName(driver.getUsername());
                driverPaymentsRecord.setDriverPhone(driver.getPhone());
                driverPaymentsRecord.setDriverCompanyId(driver.getCompanyId());
                if (payRecordDriver.getPayRecordType()
                    .equals(PayRecordDriver.PayRecordTypeDriver.alipay)) {
                    driverPaymentsRecord.setRecordType(DriverPaymentsRecord.RECHARGE_TYPE_ALIPAY);
                    driverPaymentsRecord.setMemo("支付宝充值，交易号：" + trade_no + "，充值给账号"
                        + setting.getAlipaySellerID() + "");
                } else if (payRecordDriver.getPayRecordType()
                    .equals(PayRecordDriver.PayRecordTypeDriver.wx)) {
                    driverPaymentsRecord.setRecordType(DriverPaymentsRecord.RECHARGE_TYPE_WX);
                    driverPaymentsRecord
                        .setMemo("微信充值，交易号：" + trade_no + "，充值给账号" + setting.getWxPartnerID() + "");
                } else if (payRecordDriver.getPayRecordType().equals(
                    PayRecordDriver.PayRecordTypeDriver.unionpay)) {
                    driverPaymentsRecord.setRecordType(DriverPaymentsRecord.RECHARGE_TYPE_UNIONPAY);
                    driverPaymentsRecord
                        .setMemo("银联充值，交易号：" + trade_no + "，充值给账号" + setting.getMerId() + "");
                } else if (payRecordDriver.getPayRecordType().equals(
                    PayRecordDriver.PayRecordTypeDriver.bestpay)) {
                    driverPaymentsRecord.setRecordType(DriverPaymentsRecord.RECHARGE_TYPE_BESTPAY);
                    driverPaymentsRecord
                        .setMemo("翼支付充值，交易号：" + trade_no + "，充值给账号" + setting.getMerId() + "");
                }
                driverPaymentsRecord.setOperating(DriverPaymentsRecord.OPERATING_SYS);
                driverPaymentsRecord.setRcType(DriverPaymentsRecord.DIFFERENT_POSITIVE);
                driverPaymentsRecord.setHappend(new Date());
                driverPaymentsRecordMapper.insertRecord(driverPaymentsRecord);
            }
            // 交易成功
            payRecordDriver.setTreatment(true);
            payRecordDriverMapper.updateByPrimaryKey(payRecordDriver);
            logger.info("driver id={}, trade_no={},type={}", driver.getId(), trade_no, type);
        }
    }

    @Override
    public List<Driver> queryNearFreightDrivers(Double longitude, Double latitude) {

        Setting setting = settingUtils.get();

        Double km = setting.getNearFreightDriversKm();
        SquareLocation squareLocation = Distance.returnSquarePoint(longitude, latitude, km);

        List<Driver> allDrivers = null;

        if (km != 0) {
            allDrivers = driverMapper.selectByNearlyWorkingFreight(squareLocation);
        } else {
            allDrivers = driverMapper.selectByNearlyWorkingFreight(null);
        }

        if (!CollectionUtils.isEmpty(allDrivers)) {
            for (Driver driver : allDrivers) {
                // 计算距离
                double distance = Distance.doubleVal(latitude, longitude, driver.getLatitude(),
                    driver.getLongitude());
                driver.setDistance(distance);
                DecimalFormat df = new DecimalFormat("#.00");
                if (distance >= 1) {
                    driver.setDistanceStr(df.format(distance) + "公里");
                } else {
                    driver.setDistanceStr((long) (distance * 1000) + "米");
                }
            }

            Collections.sort(allDrivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

            Collections.sort(allDrivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getStatus().compareTo(arg1.getStatus());
                }
            });
        }

        return allDrivers;
    }

    @Override
    public List<Driver> queryNearDrivers2(Long driverId, Double longitude, Double latitude) {

        Setting setting = settingUtils.get();

        Double km = setting.getNearDriversKm2();
        Integer amount = setting.getNearDriversAmount2();

        List<Driver> allDrivers = null;

        if (km != 0) {
            SquareLocation squareLocation = Distance.returnSquarePoint(longitude, latitude, km);
            squareLocation.driverId = driverId;
            allDrivers = driverMapper.selectByNearlyWorking(squareLocation);
        } else {
            SquareLocation squareLocation = new SquareLocation();
            squareLocation.driverId = driverId;
            allDrivers = driverMapper.selectByNearlyWorking(squareLocation);
        }

        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(allDrivers)) {
            for (Driver driver : allDrivers) {
                // 计算距离
                double distance = Distance.doubleVal(latitude, longitude, driver.getLatitude(),
                    driver.getLongitude());
                driver.setDistance(distance);
                DecimalFormat df = new DecimalFormat("#.00");
                if (distance >= 1) {
                    driver.setDistanceStr(df.format(distance) + "公里");
                } else {
                    driver.setDistanceStr((long) (distance * 1000) + "米");
                }
            }

            Collections.sort(allDrivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

        }

        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(allDrivers) && amount != 0
            && allDrivers.size() > amount) {
            allDrivers = allDrivers.subList(0, amount);
        }

        return allDrivers;
    }

    @Override
    public List<Driver> wxQueryDriver(Double longitude, Double latitude, Integer type) {

        Setting setting = settingUtils.get();

        Double km = setting.getNearDriversKm();
        Integer amount = setting.getNearDriversAmount();

        SquareLocation squareLocation = Distance.returnSquarePoint(longitude, latitude, km);

        List<Driver> allDrivers = null;

        if (null == type || type == 0) {// 代驾
            if (km != 0) {
                allDrivers = driverMapper.selectWeixinDriverByDaijia(squareLocation);
            }
        }

        if (!CollectionUtils.isEmpty(allDrivers)) {
            for (Driver driver : allDrivers) {
                // 计算距离
                double distance = Distance.doubleVal(latitude, longitude, driver.getLatitude(),
                    driver.getLongitude());
                driver.setDistance(distance);
                DecimalFormat df = new DecimalFormat("#.00");
                if (distance >= 1) {
                    driver.setDistanceStr(df.format(distance) + "公里");
                } else {
                    driver.setDistanceStr((long) (distance * 1000) + "米");
                }
            }

            Collections.sort(allDrivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

            Collections.sort(allDrivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getStatus().compareTo(arg1.getStatus());
                }
            });
        }

        if (!CollectionUtils.isEmpty(allDrivers) && amount != 0 && allDrivers.size() > amount) {
            allDrivers = allDrivers.subList(0, amount);
        }

        return allDrivers;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDevice(String channelID, String userID) {

        driverMapper.clearGetuiPushInfo(userID);

    }

    @Override
    public List<Driver> selectByStatus(int status) {

        return driverMapper.selectByStatus(status);

    }

    @Override
    public long countByStatus(int status) {
        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("offset", Pager.getOffset());
        params.put("size", Pager.getLimit());
        if (!principal.isCompanyType()) {
            params.put("companyId", principal.getCompanyId());
        }
        params.put("status", status);

        return driverMapper.countByPage(params);
    }

    @Override
    public long countAllLess() {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        long total = 0;

        List<Company> companys = new ArrayList<>();
        if (!principal.isCompanyType()) {
            companys.add(companyMapper.selectByPrimaryKey(principal.getCompanyId()));
        } else {
            companys.addAll(companyMapper.selectAll());
        }

        for (Company company : companys) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("companyId", company.getId());
            params.put("isFreeze", false);
            params.put("virtual", company.getLowestWorkVirtual());
            long t = driverMapper.countByPage(params);
            total += t;
        }

        return total;
    }

    @Override
    public List<Driver> findByUdid(String udid) {

        return driverMapper.selectByUdid(udid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Driver poweroffline(Long id) {

        driverMapper.updateStatusAndJobStatusByPrimaryKey(Driver.DRIVER_OFFLINE, null, id);

        return driverMapper.selectByPrimaryKey(id);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void jiebang(Long id) {

        driverMapper.jiebang(id);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void online(Driver driver) {

        driverMapper.online(Driver.DRIVER_ONLINE, driver.getId());

        DriverOnlineEvent driverOnlineEvent = new DriverOnlineEvent(driver);
        applicationEventMulticaster.multicastEvent(driverOnlineEvent);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void audit(Driver driver, Long applyId) {

        driverMapper.insertRecord(driver);
        driverApplyMapper.deleteByPrimaryKey(applyId);

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        List<Company> companys = companyMapper.selectAll();
        for (Company company : companys) {
            if (!company.getId().equals(principal.getCompanyId())) {
                DriverChoseLevel driverChoseLevel = new DriverChoseLevel();
                driverChoseLevel.setCompanyId(company.getId());
                driverChoseLevel.setDriverId(driver.getId());
                driverChoseLevel.setDriverlevelId(0L);
                driverChoseLevelMapper.insertRecord(driverChoseLevel);

                DriverChoseLevelCar driverChoseLevelCar = new DriverChoseLevelCar();
                driverChoseLevelCar.setCompanyId(company.getId());
                driverChoseLevelCar.setDriverId(driver.getId());
                driverChoseLevelCar.setDriverlevelId(0L);
                driverChoseLevelCarMapper.insertRecord(driverChoseLevelCar);

                DriverChoseLevelPaotui driverChoseLevelPaotui = new DriverChoseLevelPaotui();
                driverChoseLevelPaotui.setCompanyId(company.getId());
                driverChoseLevelPaotui.setDriverId(driver.getId());
                driverChoseLevelPaotui.setDriverlevelId(0L);
                driverChoseLevelPaotuiMapper.insertRecord(driverChoseLevelPaotui);

                DriverChoseLevelFreight driverChoseLevelFreight = new DriverChoseLevelFreight();
                driverChoseLevelFreight.setCompanyId(company.getId());
                driverChoseLevelFreight.setDriverId(driver.getId());
                driverChoseLevelFreight.setDriverlevelId(0L);
                driverChoseLevelFreightMapper.insertRecord(driverChoseLevelFreight);
            }
        }

    }

    @Override
    public List<Driver> listmodeDrivers() {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Company company = companyMapper.selectByPrimaryKey(principal.getCompanyId());

        return driverMapper.selectByWorkingArea(principal.isCompanyType() ? null : company
            .getCityName());

    }

    @Override
    public List<Driver> findAll() {

        return driverMapper.selectAll();
    }

    @Override
    public List<Driver> findAllByCompanyId(Long companyId) {

        return driverMapper.selectAllByCompany(companyId);
    }

    @Override
    public List<Driver> queryWorkCarPaidan(Long companyID, Long driverID) {

        Company company = companyMapper.selectByPrimaryKey(companyID);

        String driverJobType = "%" + Driver.DriverJobType.daijia + "%";

        return driverMapper.selectByAreaNotIncludeSelf(
            company.isCompanyType() ? null : company.getCityName(), driverID, driverJobType);

    }

    @Override
    public Page<Driver> queryZhuandanEmploys(Long companyId, Long employId, Integer page,
        Integer limit) {

        Pageable pageable = null;
        Integer offset = null;
        if (null != page && null != limit) {
            pageable = new PageRequest(page, limit);
            offset = page * limit;
        }

        Company company = companyMapper.selectByPrimaryKey(companyId);
        String cityName = null;
        if (!company.isCompanyType()) {
            cityName = company.getCityName();
        }

        String driverJobType = "%" + Driver.DriverJobType.daijia + "%";

        List<Driver> content = driverMapper.selectZhuandanEmploys(cityName, employId, driverJobType,
            offset, limit);
        long total = driverMapper.countZhuandanEmploys(cityName, employId, driverJobType);

        return new PageImpl<Driver>(content, pageable, total);
    }

    @Override
    public List<Driver> queryNearly(Double centerlng, Double centerlat, Double paidanKm,
        String driverJobType) {

        SquareLocation squareLocation = Distance.returnSquarePoint(centerlng, centerlat, paidanKm);
        squareLocation.driverJobType = "%" + driverJobType + "%";

        return driverMapper.selectByNearly(squareLocation);

    }

    @Override
    public List<Driver> queryPaidanTuijian(Double centerlng, Double centerlat, Double paidanKm) {

        SquareLocation squareLocation = Distance.returnSquarePoint(centerlng, centerlat, paidanKm);

        List<Driver> drivers = driverMapper.selectPaidanTuijian(squareLocation);

        if (!CollectionUtils.isEmpty(drivers)) {
            for (Driver driver : drivers) {
                // 计算距离
                double distance = Distance.doubleVal(centerlat, centerlng, driver.getLatitude(),
                    driver.getLongitude());
                driver.setDistance(distance);
            }

            Collections.sort(drivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

        }

        return drivers;

    }

    @Override
    public List<Driver> queryByKeyword(String keyword) {

        if (StringUtils.isEmpty(keyword)) {
            return null;
        }

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("status", Driver.DRIVER_OFFLINE);
        params.put("isFreeze", false);
        params.put("name", "%" + keyword + "%");

        return driverMapper.selectByParams(params);
    }

    @Override
    public List<Driver> listValid(Long companyId) {

        return driverMapper.selectByWorking(companyId);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateLocation(Double longitude, Double latitude, Double lastlongitude,
        Double lastlatitude, String currentAddress, Long driverId) {

        driverMapper.updatePosByPrimaryKey(longitude, latitude, lastlongitude, lastlatitude,
            currentAddress, driverId);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePosUpdated(Long driverId, Date posUpdated) {

        driverMapper.updatePosUpdated(driverId, posUpdated);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void money(Long driverid, final DriverPaymentsRecord driverPaymentsRecord, String memo) {
        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();

        final Driver driver = driverMapper.selectByPrimaryKey(driverid);

        driver.setVirtual(driver.getVirtual().add(driverPaymentsRecord.getMoney()));
        driverMapper.updateVirtualByPrimaryKey(driver.getVirtual(), driver.getId());

        driverPaymentsRecord.setAfterMoney(driver.getVirtual());
        driverPaymentsRecord.setDriverId(driver.getId());
        driverPaymentsRecord.setDriverRealName(driver.getRealname());
        driverPaymentsRecord.setDriverUserName(driver.getUsername());
        driverPaymentsRecord.setDriverPhone(driver.getPhone());
        driverPaymentsRecord.setDriverCompanyId(driver.getCompanyId());
        driverPaymentsRecord.setMemo(memo);
        if (driverPaymentsRecord.getMoney().doubleValue() > 0) {
            driverPaymentsRecord.setRecordType(DriverPaymentsRecord.RECHARGE_TYPE_ADMIN);
            driverPaymentsRecord.setRcType(DriverPaymentsRecord.DIFFERENT_POSITIVE);
        } else {
            driverPaymentsRecord.setMoney(driverPaymentsRecord.getMoney().negate());
            driverPaymentsRecord.setRecordType(DriverPaymentsRecord.CONSUMED_TYPE_ADMIN);
            driverPaymentsRecord.setRcType(DriverPaymentsRecord.DIFFERENT_NEGATIVE);
        }
        driverPaymentsRecord.setOperating(principal.getUsername());
        driverPaymentsRecord.setHappend(new Date());
        driverPaymentsRecordMapper.insertRecord(driverPaymentsRecord);

        Company driverCompany = companyMapper.selectByPrimaryKey(driver.getCompanyId());
        Company main = companyMapper.selectMainCompany();
        Setting setting = settingUtils.get();
        if (!main.getId().equals(driverCompany.getId()) && setting.isSmsMainCompany()) {
            driverCompany = main;
        }
        final Company finalCompany = driverCompany;
        taskExecutor.execute(new Runnable() {
            public void run() {
                int ret = -99;
                try {
                    String chenghu = "先生";
                    if (driver.getGender().equals("女")) {
                        chenghu = "女士";
                    }

                    SmsTemplet templet = smsService
                        .findByAlias(finalCompany.getId(), SmsType.driverMoney);
                    if (null != templet && StringUtils.isNotBlank(templet.getContent())) {
                        ret = smsService.sendSms(driver.getPhone(), "driverMoney",
                            "{\"服务人员名\":\"" + driver.getName() + "\",\"称呼\":\"" + chenghu
                                + "\",\"服务人员账号\":\""
                                + driver.getUsername() + "\",\"充值金额\":\""
                                + driverPaymentsRecord.getMoney().toString() + "\"}",
                            finalCompany.getId(), 0,
                            finalCompany.getSignName());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                logger.debug("服务人员充值短信发送结果：" + ret);
            }
        });

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateVirtual(Driver driver) {
        driverMapper.updateVirtualByPrimaryKey(driver.getVirtual(), driver.getId());
    }

    @Override
    public List<Driver> findByTypeAndFreeze(String type, boolean isFreeze, Long companyId) {

        return driverMapper.selectByTypeAndFreeze(type, isFreeze ? null : false, companyId);

    }

    @Override
    public List<Driver> findByFreeze(boolean isFreeze, Long companyId) {

        return driverMapper.selectByTypeAndFreeze(null, isFreeze, companyId);

    }

    @Override
    public List<Driver> findByVirtualAndFreeze(BigDecimal lowMoney, boolean isFreeze,
        Long companyId) {

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("virtual", lowMoney);
        if (null != companyId) {
            params.put("companyId", companyId);
        }
        if (!isFreeze) {
            params.put("isFreeze", false);
        }

        return driverMapper.selectByParams(params);

    }

    @Override
    public List<Driver> findAllByFreeze(boolean isFreeze, Long companyId) {

        return driverMapper.selectByTypeAndFreeze(null, isFreeze ? null : false, companyId);

    }

    @Override
    public List<Driver> findDriver(String param) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        String likeParam = null;
        if (StringUtils.isNotBlank(param)) {
            likeParam = "%" + param + "%";
        }

        if (!principal.isCompanyType()) {
            return driverMapper.selectByCompanyWithParam(principal.getCompanyId(), likeParam);
        } else {
            return driverMapper.selectByCompanyWithParam(null, likeParam);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int clearDayOrderNums() {

        return driverMapper.resetTodayOrdersNums();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int clearMonthOrderNums() {

        return driverMapper.resetMonthOrderNums();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPassword(String base64, Long id) {

        return driverMapper.updatePasswordByPrimaryKey(base64, id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateStatus(int status, Long driverId) {

        return driverMapper.updateStatusByPrimaryKey(status, driverId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateStatusAndJobStatus(int status, Integer jobStatus, Long driverId) {

        return driverMapper.updateStatusAndJobStatusByPrimaryKey(status, jobStatus, driverId);
    }


    @Override
    public Driver findByCarId(Long carId) {
        return driverMapper.selectByCarId(carId);
    }

    @Override
    public List<Driver> listErrandDrivers(Long orderId) {
        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Company company = companyMapper.selectByPrimaryKey(principal.getCompanyId());

        String cityName = company.getCityName();

        String driverJobType = Driver.DriverJobType.paotui.toString();

        driverJobType = "%" + driverJobType + "%";

        if (principal.isCompanyType()) {
            return driverMapper.selectPaotuiPaidan(null, driverJobType);
        } else {
            return driverMapper.selectPaotuiPaidan(cityName, driverJobType);
        }
    }

    @Override
    public List<Driver> zhuanListDrivers(Double lng, Double lat, Double distance, Long passengerId,
        Long carTypeId) {
        //计算矩形方框
        SquareLocation squareLocation = Distance.returnSquarePoint(lng, lat, distance);
        squareLocation.driverJobType = "%" + Driver.DriverJobType.zhuanche.toString() + "%";
        List<Driver> drivers = driverMapper.selectByNearly(squareLocation);
        if (CollectionUtils.isEmpty(drivers)) {
            return null;
        }
        List<Driver> drivers1 = new ArrayList();
        // 预约专车
        for (Driver driver : drivers) {
            if (driver.getCarId() != null) {
                //根据快车类型筛选和可选车辆类型过滤司机
                Car car = zhuancheService.findCar(driver.getCarId());
                if (car.getCarTypeId().equals(carTypeId)) {
                    drivers1.add(driver);
                } else {
                    //如果没有匹配的快车类型,再去匹配可选车辆类型
                    List<CarTypeRel> carTypeRelList = zhuancheService.findCarTypeRelByCarTypeId(car.getCarTypeId());
                    if (null != carTypeRelList && carTypeRelList.size() > 0) {
                        for (int i = 0; i < carTypeRelList.size(); i++) {
                            if (carTypeRelList.get(i).getAccessibleType().equals(carTypeId.toString())) {
                                drivers1.add(driver);
                            }
                        }
                    }
                }
            }
        }
        //根据距离和乘客收藏司机的情况排序
        DecimalFormat df = new DecimalFormat("#.00");
        if (!CollectionUtils.isEmpty(drivers1)) {
            for (Driver driver : drivers1) {
                //计算距离
                double d = Distance
                    .doubleVal(lat, lng, driver.getLatitude(), driver.getLongitude());
                driver.setDistance(Double.valueOf(df.format(d)));
                if (d >= 1) {
                    driver.setDistanceStr(df.format(d) + "公里");
                } else {
                    driver.setDistanceStr((long) (d * 1000) + "米");
                }
                UsuallyEmploy usuallyEmploy = usuallyEmployMapper.selectByEmployAndPassenger(
                    driver.getId(), passengerId, UsuallyEmploy.ServiceType.zhuanche);
                if (null != usuallyEmploy) {
                    driver.setUsuallyEmploy(true);
                } else {
                    driver.setUsuallyEmploy(false);
                }
            }
            // TODO 要合并两个排序 收藏优先
            Collections.sort(drivers1, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });
            if (null != passengerId) {
                Collections.sort(drivers1, new Comparator<Driver>() {
                    @Override
                    public int compare(Driver arg0, Driver arg1) {
                        return arg1.getUsuallyEmploy().compareTo(arg0.getUsuallyEmploy());
                    }
                });
            }
        }
        return drivers1;
    }

    @Override
    public List<Driver> freightListDrivers(Double lng, Double lat, Double distance) {
        SquareLocation squareLocation = Distance.returnSquarePoint(lng, lat, distance);
        squareLocation.driverJobType = "%" + Driver.DriverJobType.freight.toString() + "%";

        List<Driver> drivers = driverMapper.selectByNearlyFreight(squareLocation);

        DecimalFormat df = new DecimalFormat("#.00");

        if (!CollectionUtils.isEmpty(drivers)) {
            for (Driver driver : drivers) {
                // 计算距离
                double d = Distance
                    .doubleVal(lat, lng, driver.getLatitude(), driver.getLongitude());
                driver.setDistance(Double.valueOf(df.format(d)));
                if (d >= 1) {
                    driver.setDistanceStr(df.format(d) + "公里");
                } else {
                    driver.setDistanceStr((long) (d * 1000) + "米");
                }
            }

            Collections.sort(drivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

        }

        return drivers;
    }

    @Override
    public List<Driver> errandListDrivers(Double lng, Double lat, Double distance) {
        SquareLocation squareLocation = Distance.returnSquarePoint(lng, lat, distance);
        squareLocation.driverJobType = "%" + Driver.DriverJobType.paotui.toString() + "%";

        List<Driver> drivers = driverMapper.selectByNearlyErrand(squareLocation);

        DecimalFormat df = new DecimalFormat("#.00");

        if (!CollectionUtils.isEmpty(drivers)) {
            for (Driver driver : drivers) {
                // 计算距离
                double d = Distance
                    .doubleVal(lat, lng, driver.getLatitude(), driver.getLongitude());
                driver.setDistance(Double.valueOf(df.format(d)));
                if (d >= 1) {
                    driver.setDistanceStr(df.format(d) + "公里");
                } else {
                    driver.setDistanceStr((long) (d * 1000) + "米");
                }
            }

            Collections.sort(drivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

        }

        return drivers;
    }

    @Override
    public List<Driver> zhuanxianListDrivers(Double lng, Double lat, Double distance) {

        SquareLocation squareLocation = Distance.returnSquarePoint(lng, lat, distance);
        squareLocation.driverJobType = "%" + Driver.DriverJobType.zhuanxian.toString() + "%";

        List<Driver> drivers = driverMapper.selectByNearlyZhuanxian(squareLocation);

        DecimalFormat df = new DecimalFormat("#.00");

        if (!CollectionUtils.isEmpty(drivers)) {
            for (Driver driver : drivers) {
                // 计算距离
                double d = Distance
                    .doubleVal(lat, lng, driver.getLatitude(), driver.getLongitude());
                driver.setDistance(Double.valueOf(df.format(d)));
                if (d >= 1) {
                    driver.setDistanceStr(df.format(d) + "公里");
                } else {
                    driver.setDistanceStr((long) (d * 1000) + "米");
                }
            }

            Collections.sort(drivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

        }

        return drivers;
    }

    @Override
    public List<Driver> daijiaListDrivers(Double lng, Double lat, Double distance) {

        SquareLocation squareLocation = Distance.returnSquarePoint(lng, lat, distance);
        squareLocation.driverJobType = "%" + Driver.DriverJobType.daijia.toString() + "%";

        List<Driver> drivers = driverMapper.selectByNearly(squareLocation);

        DecimalFormat df = new DecimalFormat("#.00");

        if (!CollectionUtils.isEmpty(drivers)) {
            for (Driver driver : drivers) {
                // 计算距离
                double d = Distance
                    .doubleVal(lat, lng, driver.getLatitude(), driver.getLongitude());
                driver.setDistance(Double.valueOf(df.format(d)));
                if (d >= 1) {
                    driver.setDistanceStr(df.format(d) + "公里");
                } else {
                    driver.setDistanceStr((long) (d * 1000) + "米");
                }
            }

            Collections.sort(drivers, new Comparator<Driver>() {
                @Override
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

        }

        return drivers;
    }

    @Override
    public List<Driver> listDiaoduv3(boolean loadLixian) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Integer lixian = 0;
        if (loadLixian) {
            lixian = 1;
        }
        List<Driver> firstList = new ArrayList<>();
        if (principal.isCompanyType()) {
            firstList = driverMapper.selectDiaoduv3(null, lixian);
        } else {
            Company company = companyMapper.selectByPrimaryKey(principal.getCompanyId());
            String cityName = company.getCityName();
            //获取本公司的所有驾驶员
            firstList = driverMapper.selectAllByCompany(company.getId());

        }
        //线路权限
        List<Driver> resultList = new ArrayList<>();
        for (Driver driver : firstList) {
            Long carId = driver.getZhuanxianCarId();
            if (null != carId) {
                //驾驶员绑定的车辆
                com.ybkj.daijia.server.zhuanxian.Car car = zhuanxianService.findCar(carId);
                if (null != car) {
                    //车辆绑定的线路
                    List<Line> lines = car.getLines();
                    if (null != lines || lines.size() > 0) {
                        for (Line line : lines) {
                            //判断账号是否有该线路权限
                            if (currentUser.isPermitted(line.getId().toString())) {
                                resultList.add(driver);
                                continue;
                            }
                        }
                    }
                }
            }
        }
        return firstList;
    }

    @Override
    public long countDiaoduLixian() {
        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        if (principal.isCompanyType()) {
            return driverMapper.countDiaoduLixian(null);
        } else {
            Company company = companyMapper.selectByPrimaryKey(principal.getCompanyId());
            String cityName = company.getCityName();
            return driverMapper.countDiaoduLixian(cityName);
        }
    }

    @Override
    public List<Driver> findByParamLike(String param, Long companyId) {
        return driverMapper.selectByParam("%" + param + "%", companyId);
    }

    @Override
    public List<Driver> tuijianDiaoduDrivers(Long orderId, String orderType) {
        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();
        Setting setting = settingUtils.get();

        Double latitude = null;
        Double longitude = null;

        List<Driver> drivers = new ArrayList<Driver>();
        if (orderType.equals("daijia")) {
            Order order = orderMapper.selectByPrimaryKey(orderId);
            latitude = order.getClientLatitude();
            longitude = order.getClientLongitude();

            drivers = driverMapper.selectTuijianDiaoduDaijiaDrivers();
        } else if (orderType.equals("zhuanche")) {
            try {
                com.ybkj.daijia.server.zhuan.Order order = null;

                StringBuilder builder = new StringBuilder();
                builder.append(zhuanApi.getZhuanBaseURL() + ZhuanApi.QUERY_ORDER_ONE
                    + "?orderId={orderId}&appKey={appKey}");
                Map<String, String> kv = new HashMap<String, String>();
                kv.put("orderId", String.valueOf(orderId));
                String result = zhuanApi.get(builder.toString(), kv, settingUtils.get());
                if (null != result) {
                    JSONObject jo = new JSONObject(result);
                    Integer code = jo.getInt("code");
                    if (code == 0) {
                        JSONObject data = jo.getJSONObject("data");
                        Gson gson = new GsonBuilder().setDateFormat(com.ybkj.daijia.constant.DateConstant.DATE_TIME_FORMATE).create();
                        order = gson
                            .fromJson(data.toString(), com.ybkj.daijia.server.zhuan.Order.class);
                    }
                }

                if (null != order) {
                    latitude = order.getStartLat();
                    longitude = order.getStartLng();
                    Long carTypeId = order.getCarTypeId();
                    List<Driver> driverList = driverMapper.selectTuijianDiaoduZhuancheDrivers();
                    if (!CollectionUtils.isEmpty(driverList)) {
                        for (Driver driver : driverList) {
                            if (null != driver.getCarId()) {
                                com.ybkj.daijia.server.zhuan.Car car = zhuanApi
                                    .findCar(driver.getCarId(), setting);
                                if (null != car && car.getCarTypeId().equals(carTypeId)) {
                                    UsuallyEmploy usuallyEmploy = usuallyEmployMapper
                                        .selectByEmployAndPassenger(driver.getId(),
                                            order.getPassengerId(),
                                            UsuallyEmploy.ServiceType.zhuanche);
                                    if (null != usuallyEmploy) {
                                        driver.setUsuallyEmploy(true);
                                    } else {
                                        driver.setUsuallyEmploy(false);
                                    }
                                    drivers.add(driver);
                                }
                            }
                        }
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if ("errand".equals(orderType)) {
            com.ybkj.daijia.server.errand.OrderUp order = null;
            order = errandApi.findOneOrder(orderId, setting).getResult();
            if (null != order) {
                latitude = order.getStartLat();
                longitude = order.getStartLng();

                List<Driver> allErrandDrivers = driverMapper.selectTuijianDiaoduErrandDrivers();
                for (int i = 0; i < allErrandDrivers.size(); i++) {
                    if (allErrandDrivers.get(i).getDetailedJobType()
                        .contains(order.getOrderTypeId().toString())) {
                        drivers.add(allErrandDrivers.get(i));
                    }
                }
                // drivers = driverMapper.selectTuijianDiaoduErrandDrivers();
            }
        } else if ("freight".equals(orderType)) {
            com.ybkj.daijia.server.freight.Order order = null;
            order = freightService.findOne(orderId);
            if (null != order) {
                latitude = order.getStartLat();
                longitude = order.getStartLng();

                Long truckTypeId = order.getTruckTypeId();

                List<Driver> driverList = driverMapper.selectTuijianDiaoduFreightDrivers();
                if (!CollectionUtils.isEmpty(driverList)) {
                    for (Driver driver : driverList) {
                        if (null != driver.getTruckId()) {
                            Truck truck = freightService.findTruck(driver.getTruckId());
                            if (null != truck && truck.getTruckTypeId().equals(truckTypeId)) {
                                drivers.add(driver);
                            }
                        }
                    }
                }

            }
        } else if ("zhuanxian".equals(orderType)) {
            com.ybkj.daijia.server.zhuanxian.Order order = null;
            //获取订单信息
            order = zhuanxianApi.findOne(orderId, setting).getResult();
            if (null != order) {
                //获取经纬度
                latitude = order.getStartLat();
                longitude = order.getStartLng();
                //获取线路id
                Long lineId = order.getLineId();
                //获取所有驾驶员
                List<Driver> driverList = driverMapper.selectTuijianDiaoduZhuanxianDrivers();
                if (!CollectionUtils.isEmpty(driverList)) {
                    for (Driver driver : driverList) {
                        if (null != driver.getZhuanxianCarId()) {
                            //驾驶员绑定了专线车辆，查询车辆信息
                            com.ybkj.daijia.server.zhuanxian.Car car = zhuanxianApi
                                .findOneCar(driver.getZhuanxianCarId(), setting).getResult();
                            //判断是否有车辆，并且绑定了线路
                            if (null != car && !CollectionUtils.isEmpty(car.getLines())) {
//                              Line line = car.getLines().get(0);
//                              if (line.getId().equals(lineId)) {
                                //获取车辆绑定的线路
                                List<Line> lines = car.getLines();
                                boolean exsit = false;
                                for (Line line : lines) {
                                    if (line.getId().equals(lineId)) {
                                        exsit = true;
                                        break;
                                    }
                                }
                                if (exsit) {
                                    //查询该驾驶员（已派单、已接单、到达目的地、执行中）的订单
                                    List<com.ybkj.daijia.server.zhuanxian.Order> nowOrders = zhuanxianApi
                                        .findActivedOrdersByDriver(driver.getId(),
                                            settingUtils.get());
                                    //驾驶员是否可以接单
                                    boolean success = zhuanxianService
                                        .isReceiveAnOrder(order.getPeopleNumber(),
                                            order.getOrderType(), driver.getId());
                                    if (!success) {
                                        continue;
                                    }
                                    if (!CollectionUtils.isEmpty(nowOrders)) {
                                        if (com.ybkj.daijia.server.zhuanxian.Order.TYPE_PINCHE
                                            .equals(order.getOrderType())) {
                                            long seats = 0;
                                            boolean flag = false;
                                            for (com.ybkj.daijia.server.zhuanxian.Order nowOrder : nowOrders) {
                                                if (!com.ybkj.daijia.server.zhuanxian.Order.TYPE_PINCHE
                                                    .equals(nowOrder.getOrderType())) {
                                                    flag = true;
                                                    break;
                                                }
                                                if (!nowOrder.isYuyue()) {
                                                    seats += nowOrder.getPeopleNumber();
                                                }
                                            }
                                            if (!flag) {
                                                if (seats + order.getPeopleNumber() <= car
                                                    .getRidepeopleNumber()) {
                                                    drivers.add(driver);
                                                }
                                            }
                                        } else if (com.ybkj.daijia.server.zhuanxian.Order.TYPE_BAOCHE
                                            .equals(order.getOrderType())) {

                                        } else if (com.ybkj.daijia.server.zhuanxian.Order.TYPE_JIHUO
                                            .equals(order.getOrderType())) {
                                            if (driver.getStatus() != Driver.DRIVER_OFFLINE) {
                                                boolean hasZhixing = false;
                                                boolean flag = false;
                                                for (com.ybkj.daijia.server.zhuanxian.Order nowOrder : nowOrders) {
                                                    if (com.ybkj.daijia.server.zhuanxian.Order.ORDER_STATUS_ZHIXING
                                                        .equals(nowOrder.getStatus())) {
                                                        hasZhixing = true;
                                                        break;
                                                    }
                                                    if (!com.ybkj.daijia.server.zhuanxian.Order.TYPE_JIHUO
                                                        .equals(nowOrder.getOrderType())) {
                                                        flag = true;
                                                        break;
                                                    }
                                                }
                                                if (!hasZhixing && !flag) {
                                                    drivers.add(driver);
                                                }
                                            }
                                        }
                                    } else {
                                        if (com.ybkj.daijia.server.zhuanxian.Order.TYPE_PINCHE
                                            .equals(order.getOrderType())) {
                                            long seats = 0;
                                            if (seats + order.getPeopleNumber() <= car
                                                .getRidepeopleNumber()) {
                                                drivers.add(driver);
                                            }
                                        } else {
                                            drivers.add(driver);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

            }
        }

        DecimalFormat df = new DecimalFormat("#.00");

        if (!CollectionUtils.isEmpty(drivers)) {
            for (Driver driver : drivers) {
                // 计算距离
                double distance = Distance
                    .doubleVal(latitude, longitude, driver.getLatitude(), driver.getLongitude());
                driver.setDistance(distance);
                if (distance >= 1) {
                    driver.setDistanceStr(df.format(distance) + "公里");
                } else {
                    driver.setDistanceStr((long) (distance * 1000) + "米");
                }
            }

            Collections.sort(drivers, new Comparator<Driver>() {
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

            if (orderType.equals("zhuanche")) {
                Collections.sort(drivers, new Comparator<Driver>() {
                    public int compare(Driver arg0, Driver arg1) {
                        return arg1.getUsuallyEmploy().compareTo(arg0.getUsuallyEmploy());
                    }
                });
            }

        }

        if (!CollectionUtils.isEmpty(drivers) && drivers.size() > 10) {
            drivers = drivers.subList(0, 10);
        }

        if (!CollectionUtils.isEmpty(drivers)) {
            for (Driver driver : drivers) {
                driver.setCompany(companyMapper.selectByPrimaryKey(driver.getCompanyId()));
            }
        }

        return drivers;
    }

    @Override
    public List<Driver> queryDiaoduDrivers(String keyword, Long orderId, String orderType) {

        Setting setting = settingUtils.get();

        Double latitude = null;
        Double longitude = null;

        List<Driver> drivers = new ArrayList<Driver>();
        if (orderType.equals("daijia")) {
            Order order = orderMapper.selectByPrimaryKey(orderId);
            latitude = order.getClientLatitude();
            longitude = order.getClientLongitude();

            String param = "%" + keyword + "%";
            drivers = driverMapper.selectDiaoduDaijiaDriversByParam(param);
        } else if (orderType.equals("zhuanche")) {
            try {
                com.ybkj.daijia.server.zhuan.Order order = null;

                StringBuilder builder = new StringBuilder();
                builder.append(zhuanApi.getZhuanBaseURL() + ZhuanApi.QUERY_ORDER_ONE
                    + "?orderId={orderId}&appKey={appKey}");
                Map<String, String> kv = new HashMap<String, String>();
                kv.put("orderId", String.valueOf(orderId));
                String result = zhuanApi.get(builder.toString(), kv, settingUtils.get());
                if (null != result) {
                    JSONObject jo = new JSONObject(result);
                    Integer code = jo.getInt("code");
                    if (code == 0) {
                        JSONObject data = jo.getJSONObject("data");
                        Gson gson = new GsonBuilder().setDateFormat(com.ybkj.daijia.constant.DateConstant.DATE_TIME_FORMATE).create();
                        order = gson
                            .fromJson(data.toString(), com.ybkj.daijia.server.zhuan.Order.class);
                    }
                }

                if (null != order) {

                    latitude = order.getStartLat();
                    longitude = order.getStartLng();

                    String param = "%" + keyword + "%";

                    Long carTypeId = order.getCarTypeId();

                    List<Driver> driverList = driverMapper
                        .selectDiaoduZhuancheDriversByParam(param);
                    if (!CollectionUtils.isEmpty(driverList)) {
                        for (Driver driver : driverList) {
                            if (null != driver.getCarId()) {
                                com.ybkj.daijia.server.zhuan.Car car = zhuanApi
                                    .findCar(driver.getCarId(),
                                        setting);
                                if (null != car && car.getCarTypeId().equals(carTypeId)) {

                                    UsuallyEmploy usuallyEmploy = usuallyEmployMapper
                                        .selectByEmployAndPassenger(
                                            driver.getId(), order.getPassengerId(),
                                            UsuallyEmploy.ServiceType.zhuanche);
                                    if (null != usuallyEmploy) {
                                        driver.setUsuallyEmploy(true);
                                    } else {
                                        driver.setUsuallyEmploy(false);
                                    }

                                    drivers.add(driver);
                                }
                            }
                        }
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (orderType.equals("errand")) {
            com.ybkj.daijia.server.errand.OrderUp order = errandApi.findOneOrder(orderId, setting)
                .getResult();
            latitude = order.getStartLat();
            longitude = order.getStartLng();

            String param = "%" + keyword + "%";
            List<Driver> olddrivers = driverMapper.selectDiaoduErrandDriversByParam(param);
            if (olddrivers != null) {
                for (int i = 0; i < olddrivers.size(); i++) {
                    if (olddrivers.get(i).getDetailedJobType()
                        .contains(order.getOrderTypeId().toString())) {
                        drivers.add(olddrivers.get(i));
                    }
                }
            }
            // drivers = driverMapper.selectDiaoduErrandDriversByParam(param);

        } else if ("freight".equals(orderType)) {
            com.ybkj.daijia.server.freight.Order order = freightService.findOne(orderId);
            if (null != order) {

                latitude = order.getStartLat();
                longitude = order.getStartLng();

                String param = "%" + keyword + "%";

                Long truckTypeId = order.getTruckTypeId();

                List<Driver> driverList = driverMapper.selectDiaoduFreightDriversByParam(param);
                if (!CollectionUtils.isEmpty(driverList)) {
                    for (Driver driver : driverList) {
                        if (null != driver.getCarId()) {
                            Truck truck = freightService.findTruck(driver.getTruckId());
                            if (null != truck && truck.getTruckTypeId().equals(truckTypeId)) {
                                drivers.add(driver);
                            }
                        }
                    }
                }

            }

        } else if ("zhuanxian".equals(orderType)) {
            com.ybkj.daijia.server.zhuanxian.Order order = zhuanxianApi.findOne(orderId, setting)
                .getResult();
            if (null != order) {
                latitude = order.getStartLat();
                longitude = order.getStartLng();

                String param = "%" + keyword + "%";

                Long lineId = order.getLineId();

                List<Driver> driverList = driverMapper.selectDiaoduZhuanxianDriversByParam(param);
                if (!CollectionUtils.isEmpty(driverList)) {
                    for (Driver driver : driverList) {
                        if (null != driver.getZhuanxianCarId()) {

                            com.ybkj.daijia.server.zhuanxian.Car car = zhuanxianApi.findOneCar(
                                driver.getZhuanxianCarId(), setting).getResult();
                            if (null != car && !CollectionUtils.isEmpty(car.getLines())) {
                                Line line = car.getLines().get(0);
                                if (line.getId().equals(lineId)) {
                                    List<com.ybkj.daijia.server.zhuanxian.Order> nowOrders = zhuanxianApi
                                        .findActivedOrdersByDriver(driver.getId(),
                                            settingUtils.get());
                                    if (!CollectionUtils.isEmpty(nowOrders)) {
                                        if (com.ybkj.daijia.server.zhuanxian.Order.TYPE_PINCHE
                                            .equals(order
                                                .getOrderType())) {
                                            long seats = 0;
                                            boolean flag = false;
                                            for (com.ybkj.daijia.server.zhuanxian.Order nowOrder : nowOrders) {
                                                if (!com.ybkj.daijia.server.zhuanxian.Order.TYPE_PINCHE
                                                    .equals(nowOrder
                                                        .getOrderType())) {
                                                    flag = true;
                                                    break;
                                                }
                                                if (!nowOrder.isYuyue()) {
                                                    seats += nowOrder.getPeopleNumber();
                                                }
                                            }
                                            if (!flag) {
                                                if (seats + order.getPeopleNumber() <= car
                                                    .getRidepeopleNumber()) {
                                                    drivers.add(driver);
                                                }
                                            }
                                        } else if (com.ybkj.daijia.server.zhuanxian.Order.TYPE_BAOCHE
                                            .equals(order
                                                .getOrderType())) {

                                        } else if (com.ybkj.daijia.server.zhuanxian.Order.TYPE_JIHUO
                                            .equals(order
                                                .getOrderType())) {
                                            if (driver.getStatus() != Driver.DRIVER_OFFLINE) {
                                                boolean hasZhixing = false;
                                                boolean flag = false;
                                                for (com.ybkj.daijia.server.zhuanxian.Order nowOrder : nowOrders) {
                                                    if (com.ybkj.daijia.server.zhuanxian.Order.ORDER_STATUS_ZHIXING
                                                        .equals(nowOrder.getStatus())) {
                                                        hasZhixing = true;
                                                        break;
                                                    }
                                                    if (!com.ybkj.daijia.server.zhuanxian.Order.TYPE_JIHUO
                                                        .equals(nowOrder
                                                            .getOrderType())) {
                                                        flag = true;
                                                        break;
                                                    }
                                                }
                                                if (!hasZhixing && !flag) {
                                                    drivers.add(driver);
                                                }
                                            }
                                        }
                                    } else {
                                        if (com.ybkj.daijia.server.zhuanxian.Order.TYPE_PINCHE
                                            .equals(order
                                                .getOrderType())) {
                                            long seats = 0;
                                            if (seats + order.getPeopleNumber() <= car
                                                .getRidepeopleNumber()) {
                                                drivers.add(driver);
                                            }
                                        } else {
                                            drivers.add(driver);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

            }
        }

        DecimalFormat df = new DecimalFormat("#.00");

        if (!CollectionUtils.isEmpty(drivers)) {
            for (Driver driver : drivers) {

                driver.setCompany(companyMapper.selectByPrimaryKey(driver.getCompanyId()));

                // 计算距离
                double distance = Distance.doubleVal(latitude, longitude, driver.getLatitude(),
                    driver.getLongitude());
                driver.setDistance(distance);
                if (distance >= 1) {
                    driver.setDistanceStr(df.format(distance) + "公里");
                } else {
                    driver.setDistanceStr((long) (distance * 1000) + "米");
                }
            }

            Collections.sort(drivers, new Comparator<Driver>() {
                public int compare(Driver arg0, Driver arg1) {
                    return arg0.getDistance().compareTo(arg1.getDistance());
                }
            });

            if (orderType.equals("zhuanche")) {
                Collections.sort(drivers, new Comparator<Driver>() {
                    public int compare(Driver arg0, Driver arg1) {
                        return arg1.getUsuallyEmploy().compareTo(arg0.getUsuallyEmploy());
                    }
                });
            }

        }

        return drivers;
    }

    @Override
    public Page<Map<String, Object>> driverlistData(String name, String phone, String username,
        Date start, Date end, Long[] companyId, BigDecimal virtual, Boolean isFreeze, String[] type,
        Integer[] status, Integer[] isPlatform, Boolean isLeague) {

        if (null == isFreeze) {
            isFreeze = false;
        }

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Pageable pageable = new PageRequest(Pager.getPage(), Pager.getLimit());

        String likeDriverName = null;
        String likeDriverPhone = null;
        String likeDriverNumber = null;

        if (StringUtils.isNotBlank(name)) {
            likeDriverName = "%" + name + "%";
        }
        if (StringUtils.isNotBlank(phone)) {
            likeDriverPhone = "%" + phone + "%";
        }
        if (StringUtils.isNotBlank(username)) {
            likeDriverNumber = "%" + username + "%";
        }

        List<Map<String, Object>> content = new ArrayList<Map<String, Object>>();

        if (!principal.isCompanyType()) {
            companyId = new Long[1];
            companyId[0] = principal.getCompanyId();
        }

        List<Driver> orderList = driverMapper.selectDriverList(companyId, likeDriverName,
            likeDriverPhone, likeDriverNumber, start, end, virtual, isFreeze, type, status,
            isPlatform,
            null, isLeague, Pager.getOffset(), Pager.getLimit());
        long total = driverMapper.countDriverList(companyId, likeDriverName, likeDriverPhone,
            likeDriverNumber, start, end, virtual, isFreeze, type, status, isPlatform, null, isLeague);

        ServiceSetting serviceSetting = ServiceUtil.checkOpen();

        if (total > 0) {

            for (Driver driver : orderList) {

                DateFormat format = new SimpleDateFormat("MM/dd HH:mm:ss");
                DateFormat format2 = new SimpleDateFormat("yyyy/MM/dd");

                Map<String, Object> map = new HashMap<String, Object>();
                map.put("udid", driver.getUdid() == null ? 0 : driver.getUdid());
                map.put("id", driver.getId());
                map.put("realname", driver.getRealname());
                map.put("username", driver.getUsername());
                map.put("name", driver.getName());
                map.put("phone", UseAllDataUtil.useAllDataDriver(driver.getPhone()));
                map.put("photo", driver.getPhoto());
                map.put("virtual", driver.getVirtual());
                map.put("type", driver.getType());
                map.put("status", driver.getStatus());
                map.put("appVersion", driver.getAppVersion());
                map.put("jobTime",
                    driver.getJobTime() == null ? null : format2.format(driver.getJobTime()));
                map.put("posUpdated",
                    driver.getPosUpdated() == null ? null : format.format(driver.getPosUpdated()));
                map.put("isFreeze", driver.getIsFreeze());
                map.put("jobType", driver.getDriverJobType());
                map.put("upStatus", driver.getUpStatus());
                map.put("isLeague", driver.getIsLeague());
                String grade = "";
                if (null != driver.getGradeId()) {
                    DriverGrade driverGrade = driverGradeMapper.findById(driver.getGradeId());
                    if (null != driverGrade) {
                        grade = driverGrade.getName();
                    }
                }
                map.put("driverGrade", grade);
                map.put("deviceType", driver.getDeviceType());
                Company thisCompany = companyMapper.selectByPrimaryKey(driver.getCompanyId());
                map.put("companyAbbreviation", thisCompany.getAbbreviation());

                if (serviceSetting.isDaijia()) {
                    DriverChoseLevel driverChoseLevel = driverChoseLevelMapper
                        .selectByDriverAndCompany(
                            driver.getId(), driver.getCompanyId());
                    if (null != driverChoseLevel) {
                        driver.setDriverLevel(driverLevelMapper.selectByPrimaryKey(driverChoseLevel
                            .getDriverlevelId()));
                    }
                }

                if (serviceSetting.isZhuanche()) {
                    DriverChoseLevelCar driverChoseLevelCar = driverChoseLevelCarMapper
                        .selectByDriverAndCompany(driver.getId(), driver.getCompanyId());
                    if (null != driverChoseLevelCar) {
                        driver.setDriverLevelZhuan(
                            driverLevelMapper.selectByPrimaryKey(driverChoseLevelCar
                                .getDriverlevelId()));
                    }
                }

                if (serviceSetting.isPaotui()) {
                    DriverChoseLevelPaotui driverChoseLevelPaotui = driverChoseLevelPaotuiMapper
                        .selectByDriverAndCompany(driver.getId(), driver.getCompanyId());
                    if (null != driverChoseLevelPaotui) {
                        driver.setDriverLevelPao(
                            driverLevelMapper.selectByPrimaryKey(driverChoseLevelPaotui
                                .getDriverlevelId()));
                    }
                }

                if (serviceSetting.isFreight()) {
                    DriverChoseLevelFreight driverChoseLevelFreight = driverChoseLevelFreightMapper
                        .selectByDriverAndCompany(driver.getId(), driver.getCompanyId());
                    if (null != driverChoseLevelFreight) {
                        driver.setDriverLevelFreight(driverLevelMapper
                            .selectByPrimaryKey(driverChoseLevelFreight.getDriverlevelId()));
                    }
                }

                if (serviceSetting.isZhuanxian()) {
                    if (null != driver.getZhuanxianCarId()) {
                        List<DriverChoseLevelZhuanxian> driverChoseLevelZhuanxians = driverChoseLevelZhuanxianMapper
                            .selectByDriver(driver.getId());
                        if (!CollectionUtils.isEmpty(driverChoseLevelZhuanxians)) {
                            driver.setDriverLevelZhuanxian(driverLevelMapper
                                .selectByPrimaryKey(
                                    driverChoseLevelZhuanxians.get(0).getDriverlevelId()));
                        }
                    }
                }

                map.put("driverLevel", driver.getDriverLevel());
                map.put("driverLevelZhuan", driver.getDriverLevelZhuan());
                map.put("driverLevelPao", driver.getDriverLevelPao());
                map.put("driverLevelFreight", driver.getDriverLevelFreight());
                map.put("driverLevelZhuanxian", driver.getDriverLevelZhuanxian());

                content.add(map);
            }

        }

        return new PageImpl<Map<String, Object>>(content, pageable, total);
    }

    @Override
    public List<Driver> selectDriverList(String name, String phone, String username, Date start,
        Date end, Long[] companyId, BigDecimal virtual, Boolean isFreeze, String[] type,
        Integer[] status, Integer[] isPlatform, String[] jobType) {

        if (null == isFreeze) {
            isFreeze = false;
        }

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        String likeDriverName = null;
        String likeDriverPhone = null;
        String likeDriverNumber = null;

        if (StringUtils.isNotBlank(name)) {
            likeDriverName = "%" + name + "%";
        }
        if (StringUtils.isNotBlank(phone)) {
            likeDriverPhone = "%" + phone + "%";
        }
        if (StringUtils.isNotBlank(username)) {
            likeDriverNumber = "%" + username + "%";
        }

        if (!principal.isCompanyType()) {
            companyId = new Long[1];
            companyId[0] = principal.getCompanyId();
        }

        if (null != jobType && jobType.length > 0) {
            for (int i = 0; i < jobType.length; i++) {
                jobType[i] = "%" + jobType[i] + "%";
            }
        }

        List<Driver> orderList = driverMapper.selectDriverList(companyId, likeDriverName,
            likeDriverPhone, likeDriverNumber, start, end, virtual, isFreeze, type, status,
            isPlatform,
            jobType, null, null, null);
        return orderList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> login(Driver driver) {
        driverMapper.clearGetuiPushInfo(driver.getUserID());
        driverMapper.clearJiguangPushInfo(driver.getRegistrationId());
        driverMapper.updateLoginInfoByPrimaryKey(driver);
        DriverLogin oldToken = driverLoginMapper.selectByDriver(driver.getId());
        if (oldToken != null) {
//            JiGuangEmployV4.notice(driver, "test", "JiGuangEmployV4", settingUtils.get() );
            if (log.isInfoEnabled()) {
                log.info("模拟使用激光推送到司机端");
            }
            driverLoginMapper.deleteByPrimaryKey(oldToken.getId());
        }
        DriverLogin driverLogin = null;
        if (null == driverLogin) {
            List<String> params = new LinkedList();
            params.add(driver.getUsername());
            params.add(driver.getPassword());
            params.add(String.valueOf(System.currentTimeMillis()));
            String token = DriverLogin.genToken(params);
            driverLogin = new DriverLogin();
            driverLogin.setDriverId(driver.getId());
            driverLogin.setDriverToken(token);
            Calendar calendar = Calendar.getInstance();
            driverLogin.setRefreshDate(calendar.getTime());
            calendar.add(Calendar.MINUTE, DriverLogin.VALID_TIME);
            driverLogin.setDeathDate(calendar.getTime());
            driverLogin.setPassError(0);
            driverLogin.setCodeError(0);
            driverLoginMapper.insertRecord(driverLogin);
        }
        driver.setEmployToken(driverLogin.getDriverToken());
        driver.setRefreshTokenTime(DriverLogin.VALID_TIME);
        Map<String, Object> data = new HashMap(2);
        data.put("employToken", driver.getEmployToken());
        data.put("refreshTokenTime", driver.getRefreshTokenTime());
        return data;
    }

    @Override
    public int updateGrad2NullByGrade(Long id) {
        return driverMapper.updateGrad2NullByGrade(id);
    }

    @Override
    public List<Driver> findByZhuanxianCars(List<Long> carIds) {
        return driverMapper.selectByZhuanxianCars(carIds);
    }

    @Override
    public int insertList(List<Driver> list) {
        return driverMapper.insertList(list);
    }

    @Override
    public Long countById(Long employId) {
        return driverMapper.countById(employId);
    }


    @Override
    public Map<String, Object> checkDriver(Long[] ids, HttpSession session, String basePath) {

        List<Driver> drivers = findByIdIn(ids);
        Map<String, Object> data = new HashMap<>();
        data.put("success", true);
        for (Driver driver : drivers) {
            StringBuilder sb = new StringBuilder();
            if (driver.getCarId() == null) {
                sb.append("车牌号不能为空,");
            } else {
                com.ybkj.daijia.server.zhuan.Car car = zhuanApi.findCar(driver.getCarId(),
                    settingUtils.get());
                if (car == null) {
                    sb.append("车牌号不能为空,");
                }
            }
            if (driver.getDriverLicenseValid() == null) {
                sb.append("驾驶证有效期起始时间不能为空,");
            }
            if (driver.getDriverLicenseInvalid() == null) {
                sb.append("驾驶证有效期限结束时间不能为空,");
            }
            if (driver.getContractValid() == null) {
                sb.append("合同有效期起始时间不能为空,");
            }
            if (driver.getContractInvalid() == null) {
                sb.append("合同有效期结束时间不能为空,");
            }
            if (StringUtils.isBlank(driver.getAppVersion())) {
                sb.append("服务人员使用app版本号不能为空,");
            }
            if (StringUtils.isBlank(driver.getPressingName())) {
                sb.append("紧急情况联系人不能为空,");
            }
            if (StringUtils.isBlank(driver.getPressingPhone())) {
                sb.append("紧急情况联系人电话不能为空,");
            }
            if (StringUtils.isBlank(driver.getEmergencyAddress())) {
                sb.append("紧急情况联系人通信地址不能为空,");
            }
            if (StringUtils.isBlank(driver.getPhoto())) {
                sb.append("服务人员头像不能为空,");
            } else {
                File file = new File(basePath + "/upload/driver/" + driver.getPhoto());
                if (!file.exists()) {
                    sb.append("服务人员头像不能为空,");
                }
            }
            if (StringUtils.isBlank(driver.getLicense())) {
                sb.append("服务人员驾驶证不能为空,");
            } else {
                File file = new File(basePath + "/upload/license/" + driver.getLicense());
                if (!file.exists()) {
                    sb.append("服务人员驾驶证不能为空,");
                }
            }
            if (sb.length() > 0) {
                data.put(driver.getRealname(), sb.toString());
                data.put("success", false);
            }
        }
        return data;
    }

    @Override
    public void uploadDriver(Long[] ids, String basePath) {

        final List<Driver> byIdIn = findByIdIn(ids);
        final String finalBasePath = basePath;
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (Driver driver : byIdIn) {
                    driver.setFlag(1);
                    superviceService.SjbaMessage(driver, finalBasePath);
                }
            }
        }).start();

    }

    @Override
    public void updateDriverCarId(Long id, Long carId) {
        driverMapper.updateCarId(id, carId);
    }

    @Override
    public Page<DriverLoginRecord> loginListData(String param, Long[] companyId) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Pageable pageable = new PageRequest(Pager.getPage(), Pager.getLimit());

        String likeParam = null;

        if (StringUtils.isNotBlank(param)) {
            likeParam = "%" + param + "%";
        }

        if (!principal.isCompanyType()) {
            companyId = new Long[1];
            companyId[0] = principal.getCompanyId();
        }

        List<DriverLoginRecord> list = driverLoginRecordMapper.selectList(companyId, likeParam,
            Pager.getOffset(), Pager.getLimit());
        long total = driverLoginRecordMapper.countList(companyId, likeParam);

        return new PageImpl<DriverLoginRecord>(list, pageable, total);
    }

    @Override
    public Map<String, Object> getCodeV3(final String phone, Driver driver) {

        Company company = companyMapper.selectByPrimaryKey(driver.getCompanyId());

        String abbreviation = "";
        if (null != company) {
            abbreviation = company.getAbbreviation();
        } else {
            company = companyMapper.selectMainCompany();
            abbreviation = company.getAbbreviation();
        }

        final String abbreviation2 = abbreviation;

        PhoneSmsRecord oldPhoneSmsRecord = phoneSmsRecordMapper.selectByPhone(phone);
        if (null == oldPhoneSmsRecord) {
            final String code = String.valueOf(RandomString.randomNum(6));
            oldPhoneSmsRecord = new PhoneSmsRecord();
            oldPhoneSmsRecord.setExpired(new Date());
            oldPhoneSmsRecord.setPhone(phone);
            oldPhoneSmsRecord.setVcode(code);
            oldPhoneSmsRecord.setCompanyId(company.getId());
            phoneSmsRecordMapper.insertRecord(oldPhoneSmsRecord);
        } else {
            if ((System.currentTimeMillis() - oldPhoneSmsRecord.getExpired().getTime())
                > 1000 * 60 * 30) {
                final String code = String.valueOf(RandomString.randomNum(6));
                oldPhoneSmsRecord.setVcode(code);
                oldPhoneSmsRecord.setExpired(new Date());
                oldPhoneSmsRecord.setCompanyId(company.getId());
                phoneSmsRecordMapper.updateByPrimaryKey(oldPhoneSmsRecord);
            }
        }

        final String code = oldPhoneSmsRecord.getVcode();
        logger.debug("验证码1：" + code);

        Company main = companyMapper.selectMainCompany();
        Setting setting = settingUtils.get();
        if (!main.getId().equals(company.getId()) && setting.isSmsMainCompany()) {
            company = main;
        }
        final Company finalCompany = company;
        taskExecutor.execute(new Runnable() {
            public void run() {
                int ret = -99;
                try {
                    SmsTemplet templet = smsService
                        .findByAlias(finalCompany.getId(), SmsType.driverCode);
                    if (null != templet && StringUtils.isNotBlank(templet.getContent())
                        && StringUtils.isNotBlank(finalCompany.getSignName())) {
                        ret = smsService.sendSms(phone, "driverCode", "{\"公司名\":\"" + abbreviation2
                                + "\",\"验证码\":\"" + code + "\"}", finalCompany.getId(), 0,
                            finalCompany.getSignName());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                logger.debug("司机接受短信结果：" + ret);
            }
        });
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("create", System.currentTimeMillis());
        map.put("phone", driver.getPhone());
        return map;
    }

    @Override
    public void updateRebateMoney(BigDecimal money, Long id) {
        driverMapper.updateDriverRebate(money, id);
    }

    /***
     * 为了统一记录和金额操作, 写的方法
     * 这里要求money的正负,必须ok.
     * @param driverPaymentsRecord
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeMoneyByDriverPaymenrecord(DriverPaymentsRecord driverPaymentsRecord) {
        if (null == driverPaymentsRecord) {
            return;
        }
        Driver driver = driverMapper.selectByPrimaryKey(driverPaymentsRecord.getDriverId());
        if (null == driver) {
            return;
        }
        driver.setVirtual(driver.getVirtual().add(driverPaymentsRecord.getMoney()));
        driverPaymentsRecord.setAfterMoney(driver.getVirtual());
        driverPaymentsRecord.setDriverCompanyId(driver.getCompanyId());
        driverPaymentsRecord.setDriverPhone(driver.getPhone());
        driverPaymentsRecord.setOperating(DriverPaymentsRecord.OPERATING_SYS);
        driverMapper.updateVirtualByPrimaryKey(driver.getVirtual(), driver.getId());
        driverPaymentsRecordMapper.insertRecord(driverPaymentsRecord);
    }

    /***
     * 为了统一记录和推荐奖励金额操作, 写的方法
     * 这里要求money的正负,必须ok.
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeMoneyByDriverRebatePaymenrecord(
        DriverRebatePaymentRecord driverRebatePaymentRecord) {
        if (null == driverRebatePaymentRecord) {
            return;
        }
        Driver driver = driverMapper.selectByPrimaryKey(driverRebatePaymentRecord.getDriverId());
        if (null == driver) {
            return;
        }
        driver.setRebateMoney(driver.getRebateMoney().add(driverRebatePaymentRecord.getMoney()));
        driverRebatePaymentRecord.setAfterMoney(driver.getRebateMoney());
//        System.out.println("update driverId = " + driver.getId() +",  rebateMoney = " + driver.getRebateMoney());
        driverMapper.updateDriverRebate(driver.getRebateMoney(), driver.getId());
        driverRebatePaymentRecordMapper.insertRecord(driverRebatePaymentRecord);
    }

    @Override
    public int updateColumnsIfNotNull(Driver driver) {
        return driverMapper.updateColumnsIfNotNull(driver);
    }


}
